#pragma once

#include <SnakeLib/Direction.h>
#include <SnakeLib/ISolver.h>

#include "API.h"

using snake::EDirection;
using snake::ECellContents;

class MYSOLVER_API MySolver
  : public snake::ISolver
  {
  public:
    virtual snake::EDirection Solve(const snake::Problem &problem) override;
  };

typedef std::pair<size_t, size_t> TCoord;

struct SnakeInfo
  {
  TCoord m_head_coord;
  snake::EDirection m_direction;
  friend bool operator==(const SnakeInfo& i_left, const SnakeInfo& i_right);
  };

SnakeInfo GetSnakeInfo(const snake::Board& i_board)
  {
  SnakeInfo snake_info;

  for (size_t i = 0; i < i_board.GetHeight(); ++i)
    {
    bool done = false;
    for (size_t j = 0; j < i_board.GetWidth(); ++j)
      {
      auto content = i_board.GetCell(i, j);
      if (content == ECellContents::CELL_SNAKE_HEAD_DOWN)
        {
        snake_info.m_head_coord = std::make_pair(i,j);
        snake_info.m_direction = EDirection::DOWN;
        done = true;
        break;
        }

      if (content == ECellContents::CELL_SNAKE_HEAD_LEFT)
        {
        snake_info.m_head_coord = std::make_pair(i,j);
        snake_info.m_direction = EDirection::LEFT;
        done = true;
        break;
        }

      if (content == ECellContents::CELL_SNAKE_HEAD_UP)
        {
        snake_info.m_head_coord = std::make_pair(i,j);
        snake_info.m_direction = EDirection::UP;
        done = true;
        break;
        }

      if (content == ECellContents::CELL_SNAKE_HEAD_RIGHT)
        {
        snake_info.m_head_coord = std::make_pair(i,j);
        snake_info.m_direction = EDirection::RIGHT;
        done = true;
        break;
        }
      }
      if (done)
        break;
      }
  return snake_info;
  };

bool operator==(const SnakeInfo& i_left, const SnakeInfo& i_right)
  {
  return i_left.m_head_coord == i_right.m_head_coord && i_left.m_direction == i_right.m_direction;
  };

TCoord GetFoodCoord(const snake::Board& i_board)
  {
  for (size_t i = 0; i < i_board.GetHeight(); ++i)
    {
    for (size_t j = 0; j < i_board.GetWidth(); ++j)
      {
      auto cell_content = i_board.GetCell(i, j);
      if (cell_content == ECellContents::CELL_FOOD)
        return TCoord(i, j);
      }
    }
  throw std::logic_error("Food not found. Snake died.");
  }